package com.gzkemays.auth.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import javax.annotation.Resource;

@Configuration
@EnableWebSecurity
public class ServerWebSecurityConfig extends WebSecurityConfigurerAdapter {
  @Resource CustomLogoutSuccessHandler customLogoutSuccessHandler;

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }

  @Bean
  public static BCryptPasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }
  /**
   * 认证管理器配置，用于信息获取来源(UserDetails)以及密码校验规则(PasswordEncoder)
   *
   * @param auth
   * @throws Exception
   */
  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
        // 使用内存认证，在内存中保存两个用户
        .inMemoryAuthentication()
        .passwordEncoder(passwordEncoder())
        // admin 拥有ADMIN和USER的权限
        .withUser("admin")
        .password(passwordEncoder().encode("admin"))
        .roles("ADMIN", "USER")
        .and()
        // user 拥有USER的权限
        .withUser("user")
        .password(passwordEncoder().encode("user"))
        .roles("USER");
  }

  /**
   * 核心过滤器配置，更多使用ignoring()用来忽略对静态资源的控制
   *
   * @param web
   * @throws Exception
   */
  @Override
  public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/static/js/**");
  }
  /**
   * 安全过滤器链配置，自定义安全访问策略
   *
   * @param http
   * @throws Exception
   */
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        // /login 和 /oauth/authorize 路径配置为不需要任何身份验证，其他所有路径必须经过验证
        .antMatchers("/login", "/oauth/**","/logout","/revokeToken")
        .permitAll()
        // 其他请求都需要已认证
        .anyRequest()
        .authenticated()
        .and()
        // 使用表单登录
        .formLogin()
        // 自定义username 和password参数
        .usernameParameter("login_username")
        .passwordParameter("login_password")
        // 自定义登录页地址
        .loginPage("/loginPage")
        // 验证表单的地址，由过滤器 UsernamePasswordAuthenticationFilter 拦截处理
        .loginProcessingUrl("/login")
        .permitAll()
        .and() // 默认为 /logout
        .logout()
        .logoutSuccessHandler(customLogoutSuccessHandler)
        // 无效会话
        .invalidateHttpSession(true)
        // 清除身份验证
        .clearAuthentication(true)
        .permitAll()
        .and()
        .csrf()
        .disable();
  }

  public static void main(String[] args) {
    System.out.println(passwordEncoder().encode("user"));
  }
}
